﻿package com.cenfun.ui{
	import flash.display.*;
	import flash.events.*;
	import flash.utils.*;
	public class UI extends Sprite {
		public static const ALL:String = "all";
		public static const SIZE:String = "size";
		public static const STYLES:String = "styles";
		//===================================================
		
		protected var tw:Number;
		protected var th:Number;
		
		
		public static var inCallLaterPhase:Boolean = false;
		protected var callLaterMethods:Dictionary;
		protected var invalidHash:Object;

		public function UI():void {
			callLaterMethods = new Dictionary();
			invalidHash = {};
			
		}
		
		//设置要更新的属性到列表
		public function invalidate(property:String = UI.ALL, needCallLater:Boolean = true):void {
			invalidHash[property] = true;
			if (needCallLater) {
				callLater(draw); 
			}
		}
		
		//清空更新列表
		protected function validate():void {
			invalidHash = {};
		}
		
		protected function draw():void {
			validate();
		}
		
		//舞台呈现时更新
		protected function callLater(fn:Function):void {
			if (inCallLaterPhase) { 
				return; 
			}
			callLaterMethods[fn] = true;
			if (stage != null) {
				addRenderEvent();
			} else {
				addEventListener(Event.ADDED_TO_STAGE, callLaterDispatcher, false, 0, true);
			}
		}
		
		private function addRenderEvent():void {
			removeEventListener(Event.ADDED_TO_STAGE, callLaterDispatcher);
			stage.addEventListener(Event.RENDER, callLaterDispatcher, false, 0, true);
			stage.invalidate();
		}
		
		private function callLaterDispatcher(e:Event):void {
			if (e.type == Event.ADDED_TO_STAGE) {
				addRenderEvent();
				return;
			} else {
				e.target.removeEventListener(Event.RENDER, callLaterDispatcher);
				if (stage == null) {
					addEventListener(Event.ADDED_TO_STAGE, callLaterDispatcher, false, 0, true);
					return;
				}
			}

			inCallLaterPhase = true;
			var methods:Dictionary = callLaterMethods;
			for (var method:Object in methods) {
				method();
				delete(methods[method]);
			}
			inCallLaterPhase = false;
		}
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		public function move(_x:Number, _y:Number):void {
			x = _x;
			y = _y;
		}
		
		override public function set width(v:Number):void {
			if (tw != v) {
				tw = v;
				layout();
			}
		}
		override public function get width():Number {
			return tw;
		}
		
		override public function set height(v:Number):void {
			if (th != v) {
				th = v;
				layout();
			}
		}
		override public function get height():Number {
			return th;
		}
		
		public function size(vw:Number, vh:Number):void {
			if (tw != vw || th != vh) {
				tw = vw;
				th = vh;
				layout();
			}
		}
		
		
		public function layout():void {
			//just for override
		}
		
		
		
		
		protected function getDisplayObjectInstance(skin:Object):DisplayObject {
			var classDef:Object = null;
			if (skin is Class) { 
				return (new skin()) as DisplayObject; 
			} else if (skin is DisplayObject) {
				var obj:DisplayObject = skin as DisplayObject;
				obj.x = 0;
				obj.y = 0;
				return obj;
			}
			try {
				classDef = getDefinitionByName(skin.toString());
			} catch(e:Error) {
				try {
					classDef = loaderInfo.applicationDomain.getDefinition(skin.toString()) as Object;
				} catch (e:Error) {
				}
			}
			
			if (classDef == null) {
				return null;
			}
			return (new classDef()) as DisplayObject;
		}
		
	}
}